import zTreeUtils from "../../experience/utils/zTreeUtils.js";
import component from "../Component.js"
import VideoManager from "../VideoManager/VideoManager.js"
import {ServiceType, LayerType,staffStatusTextDict,broadcastStatusDict} from "../../experience/db/SafeMonitorType.js"
import Type from "../../experience/db/Type.js";
import {URL} from "../../configure/Assets.js"
import {treeNodeParentDict} from "../../experience/db/SafeMonitorType.js";
const Overlay = ol.Overlay;
const Draw = ol.interaction.Draw;
// 最外层目录的那几个节点的名称
const rootNodeList = [
    '安全监控',
    '人员定位',
    '应急广播',
    '视频监控',
    '通风系统'
]



export default class zTreeData extends component {
    constructor() {
        super()
    }

    async control() {
        // 创建 摄像头的视频管理器组件实例
        this.videoManager = new VideoManager({hlsUrl:URL.HLS_URL})
        // 创建 相关overlay的容器
        const staff_overlay_container = document.getElementById("sm_staffinfo_overlay");
        const broadcast_overlay_container = document.getElementById("sm_broadcastinfo_overlay")
        const video_overlay_container = document.getElementById("sm_videoinfo_overlay")
        const gas_overlay_container = document.getElementById("sm_gasinfo_overlay")
        const close_panel_staff = document.getElementById("sm_staff_panel_close")
        const close_panel_broadcast = document.getElementById("sm_broadcast_panel_close")
        const close_panel_video = document.getElementById("sm_video_panel_close")
        const close_panel_gas = document.getElementById("sm_gas_panel_close")
        // 保存 安全监控，监控系统，地下广播系统的小眼睛的状态 (true代表打开状态，false代表关闭状态)
        this.SafeMonitorEyesStatus = true
        this.MonitorEyesStatus = true
        this.BroadCastEyesStatus = true
        // 为人员分站的overlay添加关闭按钮点击行为
        close_panel_staff.addEventListener("click",(e) => {
            console.log('close-staff-info')
            this.staff_overlay.setPosition(undefined)
        })
        // 为地下广播的overlay添加关闭按钮点击行为
        close_panel_broadcast.addEventListener("click",(e) => {
            console.log('close-broadcast-info')
            this.broadcast_overlay.setPosition(undefined)
        })
        // 为监控系统摄像头的overlay添加关闭按钮点击行为
        close_panel_video.addEventListener("click",(e) => {
            this.video_overlay.setPosition(undefined)
            const videoid = $('#sm_video_container video').attr('id')
            this.videoManager.removeVideo(videoid)
        })
        // 为安全监控传感器，监控分站的overlay添加关闭按钮点击行为
        close_panel_gas.addEventListener("click",(e) => {
            this.gas_overlay.setPosition(undefined)
            // const gasid = $('#sm_video_container video').attr('id')
            // this.videoManager.removeVideo(videoid)
        })
        this.ztreeUtil = new zTreeUtils()
        // 创建 人员定位分站所使用的info 弹窗 overlay
        this.staff_overlay = new Overlay({ element: staff_overlay_container,offset:[3,8],autoPan:true })
        this.broadcast_overlay = new Overlay({ element: broadcast_overlay_container,offset:[3,8],autoPan:true })
        this.video_overlay = new Overlay({ element: video_overlay_container,offset:[3,8],autoPan:true })
        this.gas_overlay = new Overlay({ element: gas_overlay_container,offset:[3,8],autoPan:true })
        this.drawer.map.addOverlay(this.staff_overlay);
        this.drawer.map.addOverlay(this.broadcast_overlay);
        this.drawer.map.addOverlay(this.video_overlay);
        this.drawer.map.addOverlay(this.gas_overlay);
        const {formatStaffTree, formatVideoTree, formatBroadCastTree,formatGasTree,formatVentilation} = await this.treeNodeDataInit()
        // 第二次 数据筛选
        const selectedStaffNodes = formatStaffTree.filter((el) => {
            return el.isselected
        })
        const selectedVideoNodes = formatVideoTree.filter((el) => {
            return el.isselected
        })
        const selectedBroadcastNodes = formatBroadCastTree.filter((el) => {
            return el.isselected
        })
        var zTreeObj;
// zTree 的参数配置，深入使用请参考 API 文档（setting 配置详解）
        var setting = {
            view: {
                fontCss: this.setFontCss,
                addDiyDom: this.addEyesIcon.bind(this)
            },
            callback: {
                onClick: async (event, treeId, treeNode) => {
                    if (rootNodeList.includes(treeNode.name)) {
                        // do nothing
                    } else {
                        const {node_id,parent_id} = treeNode
                        switch (parent_id) {
                            case treeNodeParentDict.Staff:
                                this.staffNodeClick(node_id)
                                break
                            case treeNodeParentDict.BroadCast:
                                this.broadcastNodeClick(node_id)
                                break
                            case treeNodeParentDict.Gas:
                                // 触发点击的是监控分站
                                this.gasStationNodeClick(treeNode)
                                break
                            case treeNodeParentDict.Video:
                                // 点击的是摄像头
                                this.videoNodeClick(node_id)
                                break
                            case treeNodeParentDict.Ventilate:
                                // 点击 树上的通风设备
                                this.ventilateNodeClick(node_id)
                                break
                            default:
                                // 除开上面的以外，触发点击的就只会是监控分站下的传感器了
                                this.gasSensorNodeClick(treeNode)
                                break
                        }
                    }
                }
            }
        };
// zTree 的数据属性，深入使用请参考 API 文档（zTreeNode 节点数据详解）
        var zNodes = [
            {
                name: "安全监控",id:'gas', isShowLayer:true, open: true, children: formatGasTree
            },
            {
                name: "人员定位", id:'staff', isShowLayer:true, open: true, children: selectedStaffNodes
            },
            {
                name: "应急广播", id:'broadcast', isShowLayer:true,open: true, children: selectedBroadcastNodes
            }
            // 隐藏视频监控 和 通风系统
            // {
            //     name: "视频监控", id:'video',isShowLayer:true,open: true, children: selectedVideoNodes
            // },
            // {
            //     name: "通风系统",isShowLayer:true,open: true, children: formatVentilation
            // }
        ];
        $(document).ready(function () {
            zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
        });

        // 预览模式下,gis上人员分站的点击事件回调函数
        this.emitter.on('smStaff-feature-click',async () => {
            const node_id = this.emitter.params[0]
            console.log('smStaff-feature-click-par',node_id)
            const {data} = await this.ztreeUtil.getStaffInfo(node_id,ServiceType.Staff)
            // 用promise做的一个类似装饰器的效果的 坐标转换函数
            // await this.ztreeUtil.getStaffInfo(node_id,ServiceType.Staff).then(this.ztreeUtil.position_transform)
            const {data:position} = await  this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.Staff)
            const {x,y} = position
            const {alarm,readerId,count,placement,state,save_time,p_list} = data
            const overlayTitleHtml = `编号：${readerId} | 位置：${placement} | 状态：${staffStatusTextDict[state]} | 人数：${count}`
            let overlayTableHtml = `<tr><th>卡号</th><th>姓名</th><th>部门</th><th>工种</th><th>进入时间</th></tr>`
            const tableRowHtmlList = []
            for(let i = 0;i<p_list.length;i++) {
                let intime = ''
                if (p_list[i].intime) {
                    intime = new Date(p_list[i].intime)
                    const year = intime.getFullYear()
                    const month = intime.getMonth() + 1
                    const date = intime.getDate()
                    const hour = intime.getHours()
                    const minutes = intime.getMinutes()
                    intime = `${year}-${month}-${date}-${hour}-${minutes}`
                }

                tableRowHtmlList.push(`<tr><td>${p_list[i].rfid}</td><td>${p_list[i].pname}</td><td>${p_list[i].pdepartment}</td><td>${p_list[i].duty}</td><td>${intime}</td></tr>`)
            }
            tableRowHtmlList.forEach((el) => {
                overlayTableHtml = overlayTableHtml.concat(el)
            })
            console.log('overlayTableHtml---',overlayTableHtml)
            document.getElementById('sm_page_info_staff').innerHTML = overlayTitleHtml
            document.getElementById('sm_staff_table').innerHTML = overlayTableHtml
            const normalX = this.algo.normalX(x),normalY = this.algo.normalY(y)
            this.staff_overlay.setPosition([normalX, normalY]);

        })

        // 预览模式下,gis上地下广播的点击事件回调函数
        this.emitter.on('smbroadcast-feature-click',async () => {
            const node_id = this.emitter.params[0]
            console.log('smbroadcast-feature-click-par',node_id)
            const {data} = await this.ztreeUtil.getBroadcastInfo(node_id,ServiceType.BroadCast)
            // 用promise做的一个类似装饰器的效果的 坐标转换函数
            // await this.ztreeUtil.getStaffInfo(node_id,ServiceType.Staff).then(this.ztreeUtil.position_transform)
            const {data:position} = await  this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.BroadCast)
            const {x,y} = position
            const {node_type,place,layer,lastupdatetime,state,alarm} = data
            const transformLastDate = new Date(lastupdatetime)
            const LastDateYear = transformLastDate.getFullYear(),LastDateMonth = transformLastDate.getMonth() + 1,LastDatedate = transformLastDate.getDate(),LastDatehour = transformLastDate.getHours(),LastDateminutes = transformLastDate.getMinutes(),LastDateseconds = transformLastDate.getSeconds()
            // const broadOverlayHtml = `<span>node_type:${node_type},place:${place},layer:${layer},lastupdatetime:${lastupdatetime},state:${state},alarm:${alarm}</span>`
            const broadcastTypeHtml = `<span class="infoName">类型:</span><span class="infoValue">广播终端</span>`
            const broadcastNameHtml = `<span class="infoName">名称:</span><span class="infoValue">${place}</span>`
            const broadcastLastTimeHtml = `<span class="infoName">广播时间:</span><span class="infoValue">${LastDateYear}-${LastDateMonth}-${LastDatedate} ${LastDatehour}:${LastDateminutes}:${LastDateseconds}</span>`
            const broadcastStateHtml = `<span class="infoName">状态:</span><span class="infoValue">${broadcastStatusDict[parseInt(state)]}</span>`
            document.getElementById('broadcastTypeStyle').innerHTML = broadcastTypeHtml
            document.getElementById('broadcastNameStyle').innerHTML = broadcastNameHtml
            document.getElementById('broadcastUpdateTimeStyle').innerHTML = broadcastLastTimeHtml
            document.getElementById('broadcastStateStyle').innerHTML = broadcastStateHtml
            const normalX = this.algo.normalX(x),normalY = this.algo.normalY(y)
            this.broadcast_overlay.setPosition([normalX, normalY]);

        })

        // 预览模式下,gis上监控系统下的摄像头的点击事件回调函数
        this.emitter.on('smvideo-feature-click',async () => {
            const node_id = this.emitter.params[0]
            console.log('smvideo-feature-click-par',node_id)
            const {data:videoInfo} = await this.ztreeUtil.getSelectedVideoNodes()
            const {data:videoPosition} = await this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.Video)
            const ExtractVideoInfo = videoInfo.find((info) => {
                return info.node_id == videoPosition.node_id
            })
            // 得到的摄像头相关的信息
            const resultVideoInfo = Object.assign(videoPosition,ExtractVideoInfo)
            // 提取出 创建 流媒体视频形式的video标签
            const {channel,ip,manufacture,password,port,username} = resultVideoInfo
            const option = {channel,ip,manufacture,password,port,username}
            // videoInfoArr的格式为 [video, hls, id],分别代表 生成的video标签的dom对象，hls对象（管理流媒体的），每个hls的id
            const videoInfoArr = this.videoManager.makeVideo(option)
            const videoContainer = $('#sm_video_container')
            videoContainer.html('')
            videoContainer.append(videoInfoArr[0])
            const normalX = this.algo.normalX(resultVideoInfo.x),normalY = this.algo.normalY(resultVideoInfo.y)
            this.video_overlay.setPosition([normalX,normalY])

        })
        // 预览模式下,gis上监控系统下的传感器，分站的点击事件回调函数
        this.emitter.on('smgas-feature-click',async () => {
            const node_id = this.emitter.params[0]
            console.log('smgas-feature-click-par',node_id)
            const {data:gasPosition} = await this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.Gas)
            const gasContainer = $('#sm_gas_container')
            const inlayIframe = `<iframe width="100%" height="100%" src="../graph/info.html?nodeid=${node_id}"></iframe>`
            gasContainer.html('')
            gasContainer.append(inlayIframe)
            const normalX = this.algo.normalX(gasPosition.x),normalY = this.algo.normalY(gasPosition.y)
            this.gas_overlay.setPosition([normalX,normalY])

        })
        // 开启定时器 去定时更新 gis上的传感器
        this.refreshGasTimer = setInterval(() => {
            // 先判断 安全监控菜单的小眼睛的状态 然后确定是否要重新渲染 gas图层
            console.log('this.SafeMonitorEyesStatus--',this.SafeMonitorEyesStatus)
            console.log('this.MonitorEyesStatus--',this.MonitorEyesStatus)
            console.log('this.BroadCastEyesStatus--',this.BroadCastEyesStatus)
            if(this.SafeMonitorEyesStatus) {
                this.refreshLayer(LayerType.SMGas)
            }
        },5000)

    }

    template() {
        const sm_staffinfo_overlay = `
            <div class="sm_page" id="sm_staffinfo_overlay" style="top:10px;width: 450px;">
                <div class="sm_page_title">
                    <div id="sm_page_info_staff">人员分站信息</div>
                    <i class="iconfont sm_close_icon" style="font-size: 22px; cursor: pointer;" id="sm_staff_panel_close">&#xe6ba;</i>
                </div>
                <div class="sm_page_content">
                    <table border="1" cellspacing="0" id="sm_staff_table"></table>
                </div>
            </div>
        `
        const sm_broadcastinfo_overlay = `
            <div class="sm_page" id="sm_broadcastinfo_overlay" style="top:10px;width: 450px;">
                <div class="sm_page_title">
                    <div id="sm_page_info_broadcast">地下广播站信息</div>
                    <i class="iconfont sm_close_icon" style="font-size: 22px; cursor: pointer;" id="sm_broadcast_panel_close">&#xe6ba;</i>
                </div>
                <div class="sm_page_content">
                    <div id="sm_broadcastinfo_content">
                        <div id="broadcastTypeStyle"></div>
                        <div id="broadcastNameStyle"></div>
                        <div id="broadcastUpdateTimeStyle"></div>
                        <div id="broadcastStateStyle"></div>
                    </div>
                </div>
            </div>
        `
        const treeNodesDialog = `<div id="eqDialog" class="equipSelectDialog">
                                    <div class="cardTitle">
                                        <h4 class="title_text">选择设备</h4>
                                        <div class="spaceBox"></div>
                                    </div>
                                    <ul id="treeDemo" class="ztree" style="height: 280px;margin: 0;background-color: #fff"></ul>
                                </div>`
        const sm_videoinfo_overlay = `<div id="sm_videoinfo_overlay">
                                       <div id="sm_video_container">
                                            <video 
                                             controls 
                                             muted 
                                             loop 
                                            >
                                              <source 
                                               src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app-video-courses.mp4" 
                                               type="video/mp4" 
                                              />
                                            </video>
                                        </div>
                                        <i class="iconfont sm_close_icon" style="font-size: 22px; cursor: pointer;" id="sm_video_panel_close">&#xe6ba;</i>
                                </div>`
        const sm_gasinfo_overlay = `<div id="sm_gasinfo_overlay">
                                       <div id="sm_gas_container" style="width: 1080px;height: 650px;padding: 20px;background-color: white">
                                            
                                        </div>
                                        <i class="iconfont sm_close_icon" style="font-size: 22px; cursor: pointer;" id="sm_gas_panel_close">&#xe6ba;</i>
                                </div>`
        this.$$("body").append(treeNodesDialog);
        this.$$("#article").append(sm_staffinfo_overlay);
        this.$$("#article").append(sm_broadcastinfo_overlay);
        this.$$("#article").append(sm_videoinfo_overlay);
        this.$$("#article").append(sm_gasinfo_overlay);

    }

    async treeNodeDataInit() {
        // 获取全部树节点
        const {data: staffs} = await this.ztreeUtil.getAllStaffNodes()
        const {data: broadcasts} = await this.ztreeUtil.getAllBroadCastNodes()
        const {data: videos} = await this.ztreeUtil.getAllVideoNodes()
        const {data: gass} = await this.ztreeUtil.getAllGasNodes()
        // 获取全部已被选择的树节点
        const {data: selectedStaffs} = await this.ztreeUtil.getSelectedStaffNodes()
        const {data: selectedBroadcast} = await this.ztreeUtil.getSelectedBroadCastNodes()
        const {data: selectedVideo} = await this.ztreeUtil.getSelectedVideoNodes()
        let {data: selectedGass} = await this.ztreeUtil.getSelectedGasNodes()
        // 获取通风设备
        const {data:ventination} = await this.ztreeUtil.getSmVentilation()
        // 获取全部 m_position 的位置信息
        const {data:m_position_data} = await this.api.getSmPositions(ServiceType.Mine_Id)
        // 筛选 出已经被设置过位置的 通风设备
        const ventilationData = []
        ventination.forEach((el) => {
            if(m_position_data.some((item) => {
                return item.node_id == el.id
            })) {
                el.parent_id = treeNodeParentDict.Ventilate
                el.name = `${el.id}-${el.placement}`
                el.node_id = el.id
                delete el.id
                ventilationData.push(el)
            }
        })
        // ventilationData 表示所有已被设置过位置的通风设备

        staffs.forEach((node) => {
            const flag = selectedStaffs.some((selectNode) => {
                return node.node_id == selectNode.node_id
            })
            node.isselected = flag
        })
        videos.forEach((node) => {
            const flag = selectedVideo.some((selectNode) => {
                return node.node_id == selectNode.node_id
            })
            node.isselected = flag
        })
        broadcasts.forEach((node) => {
            const flag = selectedBroadcast.some((selectNode) => {
                return node.node_id == selectNode.node_id
            })
            node.isselected = flag
        })
        let ExtractGass = this.ztreeUtil.gasNodesInfoExtract(gass)
        // 给 gas 创建树形结构
        ExtractGass = ExtractGass.filter((el) => {
            const flag = selectedGass.some((item) => {
                return item.node_id == el.node_id
            })
            return flag
        })
        const stationNodes = ExtractGass.filter((el) => {
            return el.parent_id == treeNodeParentDict.Gas
        })
        stationNodes.forEach((station) => {
            const chilren = ExtractGass.filter((el) => {
                return el.parent_id == station.node_id
            })
            station.children = chilren
        })
        return {
            formatStaffTree: staffs,
            formatVideoTree: videos,
            formatBroadCastTree: broadcasts,
            formatGasTree:stationNodes,
            formatVentilation:ventilationData
        }
    }

    setFontCss(treeId, treeNode) {
        if (rootNodeList.includes(treeNode.name)) {
            return {color: 'black'}
        }
        // 因为这是预览模式，获取过来的元素本身就全部都是已经被设置过的。所以全都设为灰色即可
        return {color: "gray"}
    }
    addEyesIcon(treeId, treeNode) {
        if(!treeNode.id) {
            return
        }
        const aObj = $("#" + treeNode.tId + "_a");
        console.log('aObj--',aObj)
        var iconStr = `<span id='eyes_icon_${treeNode.id}' class="eye_open_style"></span>`
        aObj.append(iconStr)
        const iconDom = $(`#eyes_icon_${treeNode.id}`)
        iconDom.bind('click',(e) => {
            treeNode.isShowLayer = !treeNode.isShowLayer
            let operateLayerName = ''
            switch (treeNode.name) {
                // 点击的是安全监控目录根节点
                case rootNodeList[0]:
                    operateLayerName = LayerType.SMGas
                    this.SafeMonitorEyesStatus = treeNode.isShowLayer
                    break
                // 点击的是人员定位目录根节点
                case rootNodeList[1]:
                    operateLayerName = LayerType.SMStaff
                    break
                // 点击的是井下广播目录根节点
                case rootNodeList[2]:
                    operateLayerName = LayerType.SMBroadCast
                    this.BroadCastEyesStatus = treeNode.isShowLayer
                    break
                // 点击的是监控系统目录根节点
                case rootNodeList[3]:
                    operateLayerName = LayerType.SMVideo
                    this.MonitorEyesStatus = treeNode.isShowLayer
                    break
                // 点击的是通风系统目录根节点
                case rootNodeList[4]:
                    operateLayerName = LayerType.SMVentilate
                    break
                default:
                    break
            }
            if(treeNode.isShowLayer) {
                iconDom.attr('class', 'eye_open_style')
                // 根据树节点的不同 重新渲染不同的图层
                this.refreshLayer(operateLayerName)
            }
            else {
                iconDom.attr('class', 'eye_close_style')
                console.log('是false')
                this.hiddenLayer(operateLayerName)
            }
        })
    }

    // 根据 图层类型，重新渲染 对应图层
    refreshLayer(type) {
        switch (type) {
            case LayerType.SMStaff:
                this.drawer._smstaff()
                break
            case LayerType.SMBroadCast:
                this.drawer._smbroadcast()
                break
            case LayerType.SMVideo:
                this.drawer._smvideo()
                break
            case LayerType.SMGas:
                this.drawer._smgas()
                break
            case LayerType.SMVentilate:
                this.drawer._smventilate()
                break
            default:
                break
        }

    }

// 根据 图层类型，隐藏 对应图层
    hiddenLayer(type) {
        switch (type) {
            case LayerType.SMStaff:
                this.drawer.source(LayerType.SMStaff).clear()
                break
            case LayerType.SMBroadCast:
                this.drawer.source(LayerType.SMBroadCast).clear()
                break
            case LayerType.SMVideo:
                this.drawer.source(LayerType.SMVideo).clear()
                break
            case LayerType.SMGas:
                this.drawer.source(LayerType.SMGas).clear()
                break
            case LayerType.SMVentilate:
                this.drawer.source(LayerType.SMVentilate).clear()
                break
            default:
                break
        }
    }
    // 单击人员分站
    async staffNodeClick(node_id) {
        console.log('触发了人员分站单击')
        const {data:position_staff}= await this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.Staff)
        const {x,y} = position_staff
        this.ztreeUtil.featureLocate([x,y])
    }

    // 树节点 单击地下广播节点触发函数
    async broadcastNodeClick(node_id) {
        console.log('触发了地下广播单击')
        const {data:position_broadcast}= await this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.BroadCast)
        const {x,y} = position_broadcast
        this.ztreeUtil.featureLocate([x,y])
    }

    async gasStationNodeClick(treenode) {
        const {data:position} = await this.api.getSmPosition(ServiceType.Mine_Id,treenode.node_id,ServiceType.Gas)
        const coordinate = [position.x,position.y]
        this.ztreeUtil.featureLocate(coordinate)
        // 体现 监控分站与传感器之间的从属关系
        this.ztreeUtil.highLightStationRelation(treenode)
    }
    // 单击 tree里面的摄像头
    async videoNodeClick(node_id) {
        const {data:position_video}= await this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.Video)
        const {x,y} = position_video
        this.ztreeUtil.featureLocate([x,y])
    }

    // 单击 tree里面的通风设备
    async ventilateNodeClick(node_id) {

        const {data:positionInfo} = await this.api.getSmPosition(ServiceType.Mine_Id,node_id,ServiceType.Gas)
        const {x,y} = positionInfo
        this.ztreeUtil.featureLocate([x,y])

    }

    // 单击 监控分站下的传感器
    async gasSensorNodeClick(treenode) {
        const {data:position} = await this.api.getSmPosition(ServiceType.Mine_Id,treenode.node_id,ServiceType.Gas)
        const coordinate = [position.x,position.y]
        this.ztreeUtil.featureLocate(coordinate)
        this.ztreeUtil.highLightSensorRelation(treenode)
    }


}

